<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>数组的空位</title>
</head>
<body>
  <script>
    // 数组的空位是指，数组的某一个位置没有任何值，比如Array()构造函数返回的数组，都是空位。
    Array(3);// [,,,]
    /**
     * 注意：空位不是undefined，某一个位置的值等于undefined，依然是有值的。
     * 空位是没有任何值，in运算符可以说明这一点。
    */
   0 in [undefined,undefined,undefined]; // true
   0 in [, , ,]; // false
   /**
    * 上面代码说明，第一个数组的0号位是有值的，第二个数组的0号位是没有值的
    * es5对空位的处理，已经很不一致了。大多数情况下会忽略空位。
    * --forEach(),filter(),reduce(),every()和some()都会跳过空位。
    * --map()会跳过空位，但会保留这个值。
    * --join()和toString()会将空位视为undefined,而undefined和null会被处理成空字符串。
   */
  [,'a'].forEach((x, i) => console.log(i)); // 1 这里没有打印 0 1 跳过了空位
  ['a',,'b'].filter(x => true); // ['a','b'] 跳过了空位
  [,'a'].every(x => x==='a'); // true 跳过了空位
  [1,,2].reduce((x,y) => x+y); // 3 跳过了空位
  [,'a'].some(x => x !== 'a'); // false 跳过了空位
  [,'a'].map(x => 1); // [,1] 跳过了空位 但是保留了这个值
  [,'a',undefined,null].join('#'); // "#a##"
  [,'a',undefined,null].toString() // ",a,,"
  // 而es6则是明确将空位转为undefined
  // Array.from()方法会将数组的空位，转为undefined，也就说了，这个方法不会忽略空位。
  Array.from(['a',,'b']); //  [ "a", undefined, "b" ]
  // 扩展运算符也会将空位转为undefined
  [...['a',,'b']];//[ "a", undefined, "b" ]
  // copyWithin()会连空位一起拷贝
  var a = [,'a','b',,].copyWithin(2,0);// 将从0号开始位置的数值，复制到2号位上；
  console.log(a)// [,'a',,'a']
  // fill会将空位视为正常的数组位置
  new Array(3).fill('a'); // ['a','a','a']
  //for...of循环也会遍历空位
  var arr = [,,];
  for (var i of arr) {
    console.log(i)
  }
  // 1
  // 1
  // 上面代码中数组arr有俩个空位，for...of循环并没有忽略它们，如果改成map()方遍历，空位是会跳过的
  // entries()、keys()、values()、find()和findIndex()会将空位处理成undefined。
  [...[,'a'].entries()]; // [[0,undefined], [1,"a"]]
  [...[,'a'].keys()]; // [0,1]
  [...[,'a'].values()]; // [undefined,"a"]
  [,'a'].find(x => true); // undefined
  [,'a'].findIndex(x => true) // 0
  </script>
</body>
</html>